#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
环境变量处理工具

用于加载、验证和管理环境变量
"""

import os
from pathlib import Path
from typing import Any, Dict, List, Optional, Union, Type
from functools import lru_cache

try:
    from dotenv import load_dotenv
except ImportError:
    load_dotenv = None

from .logger import get_logger

logger = get_logger(__name__)


class EnvHandler:
    """
    环境变量处理器
    
    提供环境变量的加载、验证和类型转换功能
    """
    
    def __init__(self, env_file: str = None, auto_load: bool = True):
        """
        初始化环境变量处理器
        
        Args:
            env_file: 环境变量文件路径
            auto_load: 是否自动加载环境变量文件
        """
        self.env_file = env_file or ".env"
        self.loaded_files = []
        
        if auto_load:
            self.load_env_file()
    
    def load_env_file(self, env_file: str = None) -> bool:
        """
        加载环境变量文件
        
        Args:
            env_file: 环境变量文件路径
            
        Returns:
            bool: 是否成功加载
        """
        if load_dotenv is None:
            logger.warning("python-dotenv 未安装，无法加载 .env 文件")
            return False
        
        file_path = env_file or self.env_file
        env_path = Path(file_path)
        
        if not env_path.exists():
            logger.warning(f"环境变量文件不存在: {env_path}")
            return False
        
        try:
            success = load_dotenv(env_path, override=True)
            if success:
                self.loaded_files.append(str(env_path))
                logger.info(f"已加载环境变量文件: {env_path}")
            return success
        except Exception as e:
            logger.error(f"加载环境变量文件失败: {e}")
            return False
    
    def get(self, key: str, default: Any = None, required: bool = False, 
           var_type: Type = str) -> Any:
        """
        获取环境变量值
        
        Args:
            key: 环境变量名
            default: 默认值
            required: 是否必需
            var_type: 变量类型
            
        Returns:
            Any: 环境变量值
            
        Raises:
            ValueError: 当必需的环境变量不存在时
        """
        value = os.getenv(key, default)
        
        if required and value is None:
            raise ValueError(f"必需的环境变量未设置: {key}")
        
        if value is None:
            return default
        
        return self._convert_type(value, var_type)
    
    def get_int(self, key: str, default: int = None, required: bool = False) -> Optional[int]:
        """
        获取整数类型的环境变量
        
        Args:
            key: 环境变量名
            default: 默认值
            required: 是否必需
            
        Returns:
            Optional[int]: 环境变量值
        """
        return self.get(key, default, required, int)
    
    def get_float(self, key: str, default: float = None, required: bool = False) -> Optional[float]:
        """
        获取浮点数类型的环境变量
        
        Args:
            key: 环境变量名
            default: 默认值
            required: 是否必需
            
        Returns:
            Optional[float]: 环境变量值
        """
        return self.get(key, default, required, float)
    
    def get_bool(self, key: str, default: bool = None, required: bool = False) -> Optional[bool]:
        """
        获取布尔类型的环境变量
        
        Args:
            key: 环境变量名
            default: 默认值
            required: 是否必需
            
        Returns:
            Optional[bool]: 环境变量值
        """
        return self.get(key, default, required, bool)
    
    def get_list(self, key: str, default: List[str] = None, 
                separator: str = ",", required: bool = False) -> Optional[List[str]]:
        """
        获取列表类型的环境变量
        
        Args:
            key: 环境变量名
            default: 默认值
            separator: 分隔符
            required: 是否必需
            
        Returns:
            Optional[List[str]]: 环境变量值
        """
        value = self.get(key, None, required, str)
        
        if value is None:
            return default or []
        
        return [item.strip() for item in value.split(separator) if item.strip()]
    
    def get_dict(self, key: str, default: Dict[str, str] = None, 
                separator: str = ",", kv_separator: str = "=", 
                required: bool = False) -> Optional[Dict[str, str]]:
        """
        获取字典类型的环境变量
        
        Args:
            key: 环境变量名
            default: 默认值
            separator: 项目分隔符
            kv_separator: 键值分隔符
            required: 是否必需
            
        Returns:
            Optional[Dict[str, str]]: 环境变量值
        """
        value = self.get(key, None, required, str)
        
        if value is None:
            return default or {}
        
        result = {}
        for item in value.split(separator):
            item = item.strip()
            if kv_separator in item:
                k, v = item.split(kv_separator, 1)
                result[k.strip()] = v.strip()
        
        return result
    
    def _convert_type(self, value: str, var_type: Type) -> Any:
        """
        转换变量类型
        
        Args:
            value: 字符串值
            var_type: 目标类型
            
        Returns:
            Any: 转换后的值
        """
        if var_type == str:
            return value
        elif var_type == int:
            return int(value)
        elif var_type == float:
            return float(value)
        elif var_type == bool:
            return value.lower() in ('true', '1', 'yes', 'on', 'enabled')
        else:
            return value
    
    def set(self, key: str, value: Any) -> None:
        """
        设置环境变量
        
        Args:
            key: 环境变量名
            value: 环境变量值
        """
        os.environ[key] = str(value)
        logger.debug(f"设置环境变量: {key}={value}")
    
    def unset(self, key: str) -> None:
        """
        删除环境变量
        
        Args:
            key: 环境变量名
        """
        if key in os.environ:
            del os.environ[key]
            logger.debug(f"删除环境变量: {key}")
    
    def exists(self, key: str) -> bool:
        """
        检查环境变量是否存在
        
        Args:
            key: 环境变量名
            
        Returns:
            bool: 是否存在
        """
        return key in os.environ
    
    def validate_required(self, required_vars: List[str]) -> Dict[str, bool]:
        """
        验证必需的环境变量
        
        Args:
            required_vars: 必需的环境变量列表
            
        Returns:
            Dict[str, bool]: 验证结果
        """
        results = {}
        for var in required_vars:
            exists = self.exists(var)
            results[var] = exists
            if not exists:
                logger.error(f"缺少必需的环境变量: {var}")
        
        return results
    
    def get_all_with_prefix(self, prefix: str) -> Dict[str, str]:
        """
        获取指定前缀的所有环境变量
        
        Args:
            prefix: 前缀
            
        Returns:
            Dict[str, str]: 环境变量字典
        """
        return {
            key[len(prefix):]: value 
            for key, value in os.environ.items() 
            if key.startswith(prefix)
        }
    
    def export_to_dict(self, keys: List[str] = None) -> Dict[str, str]:
        """
        导出环境变量到字典
        
        Args:
            keys: 要导出的环境变量名列表，None表示导出所有
            
        Returns:
            Dict[str, str]: 环境变量字典
        """
        if keys is None:
            return dict(os.environ)
        
        return {key: os.environ.get(key, '') for key in keys if key in os.environ}
    
    def load_from_dict(self, env_dict: Dict[str, Any], override: bool = True) -> None:
        """
        从字典加载环境变量
        
        Args:
            env_dict: 环境变量字典
            override: 是否覆盖已存在的环境变量
        """
        for key, value in env_dict.items():
            if override or key not in os.environ:
                self.set(key, value)
    
    def create_env_file(self, file_path: str, env_dict: Dict[str, Any], 
                       comments: Dict[str, str] = None) -> bool:
        """
        创建环境变量文件
        
        Args:
            file_path: 文件路径
            env_dict: 环境变量字典
            comments: 注释字典
            
        Returns:
            bool: 是否成功创建
        """
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write("# 环境变量配置文件\n")
                f.write("# 请根据实际情况修改配置值\n\n")
                
                for key, value in env_dict.items():
                    if comments and key in comments:
                        f.write(f"# {comments[key]}\n")
                    f.write(f"{key}={value}\n")
                    f.write("\n")
            
            logger.info(f"已创建环境变量文件: {file_path}")
            return True
            
        except Exception as e:
            logger.error(f"创建环境变量文件失败: {e}")
            return False
    
    def get_environment_info(self) -> Dict[str, Any]:
        """
        获取环境信息
        
        Returns:
            Dict[str, Any]: 环境信息
        """
        return {
            "loaded_files": self.loaded_files,
            "environment_count": len(os.environ),
            "python_path": os.getenv("PYTHONPATH", ""),
            "current_directory": os.getcwd(),
            "user": os.getenv("USER", os.getenv("USERNAME", "unknown")),
            "platform": os.name
        }
    
    def __str__(self) -> str:
        """
        字符串表示
        
        Returns:
            str: 环境处理器描述
        """
        return f"EnvHandler(env_file={self.env_file}, loaded_files={len(self.loaded_files)})"
    
    def __repr__(self) -> str:
        """
        对象表示
        
        Returns:
            str: 环境处理器表示
        """
        return self.__str__()


# 全局环境处理器实例
_env_handler = None


@lru_cache(maxsize=1)
def get_env_handler(env_file: str = None) -> EnvHandler:
    """
    获取环境处理器实例（单例模式）
    
    Args:
        env_file: 环境变量文件路径
        
    Returns:
        EnvHandler: 环境处理器实例
    """
    global _env_handler
    
    if _env_handler is None:
        _env_handler = EnvHandler(env_file)
    
    return _env_handler


# 便捷函数
def get_env(key: str, default: Any = None, required: bool = False, 
           var_type: Type = str) -> Any:
    """
    获取环境变量的便捷函数
    
    Args:
        key: 环境变量名
        default: 默认值
        required: 是否必需
        var_type: 变量类型
        
    Returns:
        Any: 环境变量值
    """
    return get_env_handler().get(key, default, required, var_type)


def get_env_int(key: str, default: int = None, required: bool = False) -> Optional[int]:
    """获取整数类型环境变量"""
    return get_env_handler().get_int(key, default, required)


def get_env_float(key: str, default: float = None, required: bool = False) -> Optional[float]:
    """获取浮点数类型环境变量"""
    return get_env_handler().get_float(key, default, required)


def get_env_bool(key: str, default: bool = None, required: bool = False) -> Optional[bool]:
    """获取布尔类型环境变量"""
    return get_env_handler().get_bool(key, default, required)


def get_env_list(key: str, default: List[str] = None, 
                separator: str = ",", required: bool = False) -> Optional[List[str]]:
    """获取列表类型环境变量"""
    return get_env_handler().get_list(key, default, separator, required)


def validate_env(required_vars: List[str]) -> bool:
    """
    验证必需环境变量的便捷函数
    
    Args:
        required_vars: 必需的环境变量列表
        
    Returns:
        bool: 是否全部存在
    """
    results = get_env_handler().validate_required(required_vars)
    return all(results.values())